#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <sys/time.h>
 
#include "data_type.h"
#include "cube.h"
#include "cube_define.h"
#include "cube_record.h"
#include "user_define.h"
#include "mac_label.h"
// add para lib_include
int user_label_init(void * sub_proc, void * para)
{
	int ret;
	// add yorself's module init func here
	return 0;
}
int user_label_start(void * sub_proc, void * para)
{
	int ret;
	void * recv_msg;
	int type;
	int subtype;
	// add yorself's module exec func here
	while(1)
	{
		usleep(time_val.tv_usec);
		ret=ex_module_recvmsg(sub_proc,&recv_msg);
		if(ret<0)
			continue;
		if(recv_msg==NULL)
			continue;
		type=message_get_type(recv_msg);
		subtype=message_get_subtype(recv_msg);
		if(!memdb_find_recordtype(type,subtype))
		{
			printf("message format (%d %d) is not registered!\n",
			message_get_type(recv_msg),message_get_subtype(recv_msg));
			continue;
		}
		if((type==TYPE(USER_DEFINE))&&(subtype==SUBTYPE(USER_DEFINE,LOGIN)))
		{
			ret=proc_login_addrattach(sub_proc,recv_msg);
		}
		else if((type==TYPE(USER_DEFINE))&&(subtype==SUBTYPE(USER_DEFINE,RETURN)))
		{
			ret=proc_login_addrverify(sub_proc,recv_msg);
		}
		else
		{
			printf("enter user attach proc!\n");
			ret=proc_login_userattach(sub_proc,recv_msg);
		}
	}
	return 0;
}

int proc_login_addrattach(void * sub_proc,void * recv_msg)
{
	int ret;
	RECORD(GENERAL_RETURN,UUID) * addr_label;
	RECORD(USER_DEFINE,SERVER_STATE) * server_state;
	RECORD(USER_DEFINE,LOGIN) * user_login;
	MSG_EXPAND * msg_expand;
	BYTE *proc_uuid;

	addr_label=Talloc0(sizeof(*addr_label));
	if(addr_label==NULL)
		return -ENOMEM;
	ret=message_get_record(recv_msg,&user_login,0);
	if(ret<0)
		return ret;
	proc_uuid = message_get_sender(recv_msg);

	addr_label->name = dup_str(user_login->user_name,DIGEST_SIZE);	
	Memcpy(addr_label->return_value,proc_uuid,DIGEST_SIZE);

	DB_RECORD * db_record;

	// find proc_uuid's server state
	db_record=memdb_find_first(TYPE_PAIR(USER_DEFINE,SERVER_STATE),"proc_uuid",proc_uuid);
	// if there is server_state in memdb, clear it
	if(db_record !=NULL)
	{
		server_state=db_record->record;
		Free(server_state->user_name);
		server_state->user_name=NULL;
		memdb_store_record(db_record);

	}

	// add user and uuid info in message's expand data
	ret=message_add_expand_data(recv_msg,TYPE_PAIR(GENERAL_RETURN,UUID),addr_label);
	if(ret<0)
		return ret;
	
	ret=ex_module_sendmsg(sub_proc,recv_msg);
	return ret;
}
int proc_login_addrverify(void * sub_proc,void * recv_msg)
{
	int ret;
	RECORD(GENERAL_RETURN,UUID) * addr_label;
	RECORD(USER_DEFINE,RETURN) * user_return;
	RECORD(USER_DEFINE,SERVER_STATE) * server_state;
	MSG_EXPAND * msg_expand;
	BYTE *proc_uuid;

	ret=message_get_record(recv_msg,&user_return,0);
	if(ret<0)
		return ret;

	ret=message_remove_expand(recv_msg,TYPE_PAIR(GENERAL_RETURN,UUID),&msg_expand);
	if(ret<0)
		return ret;
	if(msg_expand==NULL)
	{
		print_cubeerr("can't find addr attached!\n");	
		return -EINVAL;
	}
	addr_label=msg_expand->expand;

    	if(user_return->return_code==1)
	{

		DB_RECORD * db_record;
		db_record=memdb_find_first(TYPE_PAIR(USER_DEFINE,SERVER_STATE),"user_name",addr_label->name);
		if(db_record==NULL)
		{
			print_cubeerr("user_label: lost user %s 's proc uuid!",addr_label->name);
			return -EINVAL;
		}	
		server_state=db_record->record;
		Memcpy(server_state->proc_uuid,addr_label->return_value,DIGEST_SIZE);			

		memdb_store(server_state,TYPE_PAIR(USER_DEFINE,SERVER_STATE),NULL);
	}		

	ret=ex_module_sendmsg(sub_proc,recv_msg);
	return ret;
}

int proc_login_userattach(void * sub_proc,void * recv_msg)
{
	int ret;
	RECORD(USER_DEFINE,SERVER_STATE) * user_server;
	RECORD(MAC_LABEL,SUBJECT) * user_label;
	MSG_EXPAND * msg_expand;
	BYTE * proc_uuid;

	proc_uuid = message_get_sender(recv_msg);

	DB_RECORD * db_record;

	db_record=memdb_find_first(TYPE_PAIR(USER_DEFINE,SERVER_STATE),"proc_uuid",proc_uuid);
	if(db_record==NULL)
	{
		print_cubeerr("user_label: can't find addr!");
		return -EINVAL;
	}
	user_server=db_record->record;
	printf("find user %s in addr!\n",user_server->user_name);


	db_record=memdb_find_first(TYPE_PAIR(MAC_LABEL,SUBJECT),"user_name",user_server->user_name);
	if(db_record==NULL)
	{
		print_cubeerr("user_label: can't find label!\n");
		return -EINVAL;
	}
	
	user_label=db_record->record;

	ret=message_add_expand_data(recv_msg,TYPE_PAIR(MAC_LABEL,SUBJECT),user_label);
	if(ret<0)
		return ret;

	ret=ex_module_sendmsg(sub_proc,recv_msg);
	return ret;
}
